/*
数据的保存从行计数器的值大于某个阈值(L1)后开始的,一直到行计数器超过某个阈值(L2).

			S1		S2	  S3		S4	  S5	 S6
	L1  : RT_PRE | RT | RT_POS | LT_PRE | LT | LT_POS
	    : RT_PRE | RT | RT_POS | LT_PRE | LT | LT_POS
						......
	L2-1: RT_PRE | RT | RT_POS | LT_PRE | LT | LT_POS

上面的"简图"标出了实际保存的数据对应的"行"和状态,根据这个图可以精确计算出所保存的数据对应的总reg_clk周期数。
状态交替顺序如下:
	S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S1 ....
其中
1）S1,S3,S4,S6四个状态各占一个reg_clk周期;
2）S2对应的reg_clk周期数 = N_COL (= 27 + 1152 + overscan像元数)
3）S5对应的reg_clk周期数 = V_TRANS_PERIOD / REG_CLK_PERIOD
*/

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>

#include "dictionary.h"
#include "iniparser.h"

#ifndef __EXTRACT_WAVEFORM__
#define __EXTRACT_WAVEFORM__

#define _CCD_OSX_	0	// CCD输出的信号
#define _V_DRIVE_	1	// 垂直(行)转移驱动
#define _H_DRIVE_	2	// 水平(像元)转移驱动


//	存储（二进制）波形数据的相关属性，读出的行数、列数、时钟等信息
//	周期的单位全部用微秒（us）
typedef struct _waveform_config{
	int N_ROW;				// 采集波形时配置的保存行数
	int N_COL;				// 每一行读出的像元数(pre-scan,图像区,over-scan)
	int SAMP_NUM_PER_REG;	// 每个像元采样的次数

	int REG_CLK_NUM;		// 保存的数据对应的总像元周期数(不仅包含了图像部分,也包含了其他状态,详见上面的简图)
	int LEN;				// 16bits数据的总数目,等于REG_CLK_NUM

	int WAVE_TYPE;			// 采集的波形的类型,默认为_CCD_OSX_
	int OS_NUM;				// 如果WAVE_TYPE == _CCD_OSX_, 就需要在输出结果文件中加上通道信息
	int IMG_PHASE;			// 垂直转移驱动相位
	int REG_PHASE;			// 水平转移驱动相位(RST也归为REG驱动,用4标记)

	int S1_idx0, S1_idx1;
	int S2_idx0, S2_idx1;
	int S3_idx0, S3_idx1;
	int S4_idx0, S4_idx1;
	int S5_idx0, S5_idx1;
	int S6_idx0, S6_idx1;

	int AD_CLK_DIV;			// AD9249输入时钟50MHz"分频"参数,1,2,3...
	double AD_REF_FREQ;		// AD9249输入参考时钟50MHz(由时钟芯片决定)
	double AD_CLK_PERIOD;	// 实际AD采样周期
	double V_TRANS_PERIOD;	// 垂直转移周期（默认值为300us），用于计算一次行转移对应多少个AD_CLK周期
	double REG_CLK_PERIOD;	// 像元周期 = SAMP_NUM_PER_REG * AD_CLK_PERIOD

	char out_root[256];	// 输出结果文件名root
	char out_dir[256];		// 用于保存输出结果的目录
	char outfile[1024];     // 默认情况下为空

	int verbose;

} waveform_config;


int init_waveform_config_default( waveform_config *wf_cfg );
int init_waveform_config( waveform_config *wf_cfg, char *inifile );
int print_waveform_config( waveform_config *wf_cfg );

int extract_waveform( waveform_config *wf_cfg, char *binfile );

int write_waveform( waveform_config *wf_cfg, uint16_t *regs_u16, char *out_file );

#endif // __EXTRACT_WAVEFORM__
